package com.vcaresolution.logistic.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;

import com.vcaresolution.logistic.form.VoyageForm;
import com.vcaresolution.logistic.to.DataHolderTO;
import com.vcaresolution.logistic.to.VoyageInfo;
import com.vcaresolution.logistic.to.VoyageTO;
import com.vcaresolution.logistic.util.ApplicationConstants;
import com.vcaresolution.util.Utils;

/**
 * <code>VoyageController</code> is used to track all login related actions
 *
 * @author Snehal Shah
 * @version 1.0
 * @since ShipSoft 1.0
 */
@Controller
public class VoyageController extends BaseController{

	@ModelAttribute(value=ApplicationConstants.VOYAGEFORM_MODELATTRIBUTE)
	public VoyageForm createForm(){
		return new VoyageForm();
	}
	
	private void loadRequiredDetailInModelObject(ModelAndView modelAndView){
		modelAndView.addObject(ApplicationConstants.VESSELLIST_MODELATTRIBUTE, getServiceRegistry().getVesselService().findByAll());
		modelAndView.addObject(ApplicationConstants.PORTLIST_MODELATTRIBUTE, getServiceRegistry().getPortService().findByAll());
	}
	
	/**
	 * This method is called when the GET request has been made to the ADDVoyage Request
	 */
	@RequestMapping(value=ApplicationConstants.ADD_VOYAGE_URL,method = RequestMethod.GET)
	public ModelAndView loadAddVoyage() {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName(ApplicationConstants.ADD_VOYAGE_VIEW);
		modelAndView.addObject(ApplicationConstants.VOYAGEFORM_MODELATTRIBUTE, new VoyageForm());
		
		loadRequiredDetailInModelObject(modelAndView);
		
		return modelAndView;
	}
	
	/**
	 * This method is called when the POST request has been made to the ADDVoyage Request
	 */
	@RequestMapping(value=ApplicationConstants.ADD_VOYAGE_URL,method = RequestMethod.POST)
	public ModelAndView processAddVoyage(@Valid VoyageForm voyageForm, final BindingResult result,final HttpServletRequest request,final RedirectAttributes redirectAttrs) {
		ModelAndView modelAndView = new ModelAndView();
		
		System.out.println("Inside Controller : "+result.hasErrors());
		
		if( !result.hasErrors() ){
			voyageForm.setUser(getLoggedInUser(request));
			getServiceRegistry().getVoyageService().add(voyageForm);
			
			modelAndView.setView(new RedirectView(ApplicationConstants.LIST_VOYAGE_URL, true, true, false));
		}
		else{
			loadRequiredDetailInModelObject(modelAndView);
		}
		
		return modelAndView;
	}
	
	/**
	 * This method is called when the GET request has been made to the ListVoyage Request
	 */
	@RequestMapping(value=ApplicationConstants.LIST_VOYAGE_URL,method = RequestMethod.GET)
	public ModelAndView list() {
		final ModelAndView modelAndView = new ModelAndView();
		
		List<VoyageTO> voyageList = getServiceRegistry().getVoyageService().findByAll();
		
		modelAndView.addObject(ApplicationConstants.VOYAGELIST_MODELATTRIBUTE, voyageList);
		modelAndView.setViewName(ApplicationConstants.LIST_VOYAGE_VIEW);
		return modelAndView;
	}
	
	/**
	 * This method is called when the GET request has been made to the ADDVoyage Request
	 */
	@RequestMapping(value=ApplicationConstants.EDIT_VOYAGE_URL,method = RequestMethod.GET)
	public  ModelAndView loadEditVoyage(@RequestParam(value="voyageId") String voyageID) {
		ModelAndView modelAndView = new ModelAndView();
		
		Object voyageObject = getServiceRegistry().getVoyageService().findById(Integer.parseInt(voyageID));
		
		modelAndView.addObject(ApplicationConstants.VOYAGEFORM_MODELATTRIBUTE, voyageObject);
		loadRequiredDetailInModelObject(modelAndView);
		
		modelAndView.setViewName(ApplicationConstants.EDIT_VOYAGE_VIEW);
		
		return modelAndView;
	}
	
	/**
	 * This method is called when the POST request has been made to the ADDVoyage Request
	 */
	@RequestMapping(value=ApplicationConstants.EDIT_VOYAGE_URL,method = RequestMethod.POST)
	public ModelAndView processEditVoyage(@Valid VoyageForm voyageForm, final BindingResult result,final HttpServletRequest request,final RedirectAttributes redirectAttrs) {
		ModelAndView modelAndView = new ModelAndView();
		
		System.out.println("Inside Controller :: "+result.hasErrors());
		
		if( !result.hasErrors() ){
			voyageForm.setUser(getLoggedInUser(request));
			getServiceRegistry().getVoyageService().update(voyageForm);
			
			modelAndView.setView(new RedirectView(ApplicationConstants.LIST_VOYAGE_URL, true, true, false));
		}
		else{
			loadRequiredDetailInModelObject(modelAndView);
		}		
		return modelAndView;
	}
	
	@RequestMapping(value =ApplicationConstants.GET_VOYAGE_URL, method = RequestMethod.POST, produces = "application/json")
	public @ResponseBody
	VoyageInfo populateCityForState(@RequestParam(required = true, value = "voyageId") final String voyageId) {
		VoyageTO voyageTO = getServiceRegistry().getVoyageService().findById(Integer.parseInt(voyageId));
		
		VoyageInfo voyageInfo = new VoyageInfo();
		
		voyageInfo.setCutOffDate(Utils.convertDateObjectToDDMMYYYY(voyageTO.getCutoff()));
		voyageInfo.setEtdDate(Utils.convertDateObjectToDDMMYYYY(voyageTO.getEtd()));
		
		return  voyageInfo;
	}
}